# -*- coding: utf-8 -*-
"""
:mod:`nubio.data.score`
=======================

The ``nubio.data.score`` module provides pairwise scoring matrices.

"""
from files import _MATRICES
import math


def parse_score_matrix(fh):
    """
    Parses a score matrix, which in the format of the matrices available at:
    ftp://ftp.ncbi.nih.gov/blast/matrices/. Code from adapted from:
    http://bitbucket.org/brentp/biostuff/src/tip/nwalign/pairwise.py
    Author:  brentp <bpederse at gmail com>. Returns a nested ``dict`` 
    representation of the 2D-matrix.
    
    Arguments:
    
        - fh(``file``) A file-like object open for reading.
    
    """
    m = {}
    headers = None
    while headers is None:
        line = fh.readline().strip()
        if not line or line[0] == '#':
            continue
        headers = [x for x in line.split(' ') if x]
        for h in headers: m[h] = {}
    line = fh.readline()
    while line:
        h1 = line[0]
        line = [int(x) for x in line[1:-1].split(' ') if x]
        values = zip(headers, line)
        m[h1] = dict(values)
        line = fh.readline()
    return m

def exponent_score_matrix(sm, scale=1.0):
    """
    Exponentiates a score matrix object "sm" and optionally scales it by 
    "scale".
    
    Arguments:
    
        - sm(``dict``) a scoring matrix dictionary see: ``parse_score_matric``.
        - scale(``float``) [default: ``1.0``] an optional scale factor.
        
    """
    Q = {}
    symbols = sm.keys()
    for symbol1 in symbols:
        Q[symbol1] = {}
        for symbol2 in symbols:
            Q[symbol1][symbol2] = math.exp(scale * sm[symbol1][symbol2])
    return Q

def parse_blosum_out(fh):
    """
    Parser for a blosumXX.out file. Returns a dictionary.
    
    Arguments:
    
        - fh(``file``) A file-like object open for reading.
        
    """
    result = {}
    if not fh.readline().startswith('BLOSUM'):
        raise ValueError('Not a valid blosumXX.out file.')
    line = fh.readline()
    while line:
        if line.startswith('Re-clustering'):
            id_ = line.split()[-1]
        if line.startswith('AA Probabilities'):
            aa = fh.readline().split()
            fi = [float(f) for f in fh.readline().split()]
            result['fi'] = dict(zip(aa, fi))
        line = fh.readline()
    return (id_, result)

# insert parsed matrices into global namespace
for fn, fh in _MATRICES:
    sm = parse_score_matrix(fh)
    globals()[fn] = sm







